home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
-
- #include <gl.h>
- #include <device.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <bstring.h>
- #include <errno.h>
- #include <assert.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/signal.h>
- #include <sys/fcntl.h>
- #include <sys/errno.h>
- #include <sys/stat.h>
- #include <netinet/in.h>
- #include <sys/time.h>
- #include "gizmo.h"
- #include "generic.h"
- #include "cmds.h"
- #ifdef __cplusplus
- #include <osfcn.h>
- #include <stdarg.h>
- #else
- #include <varargs.h>
- #endif
-
- int gd;
- gizmo_t *gizmoptr;
-
- /* gd = qgetfd(); XXX */
-
-
- gizmo_t browsegizmo = {
- "/usr/lib/jot/browsegizmo", /* name */
- 0, /* fd */
- 0, /* pid */
- 0, /* llx */
- 0, /* lly */
- 0, /* xsize */
- 0, /* ysize */
- 0, /* state */
- 0, /* initme */
- 0, /* killme */
- 0, /* next */
-
- };
-
- static void senddev(gizmo_t *gp, long dev)
- {
- if (gp->fd == 0) return;
- if (write(gp->fd, &dev, sizeof(dev)) < 0) {
- perror("writing stream message");
- exit(1);
- }
- }
-
- static void senddevval(gizmo_t *gp, long dev, long val)
- {
- long buf[2];
-
- if (gp->fd == 0) return;
- buf[0] = dev;
- buf[1] = val;
- if (write(gp->fd, buf, sizeof(buf)) < 0) {
- perror("writing stream message");
- exit(1);
- }
- }
-
- static long readbuf(int fd, char *p, int totbytes)
- {
- int nbytes, n;
-
- nbytes = 0;
- while (nbytes < totbytes) {
- if ( (n=read(fd,p+nbytes,totbytes-nbytes)) < 0) {
- if (errno == EINTR) continue;
- perror("Read failure");
- return -1;
- }
- if (n == 0)
- break;
- nbytes += n;
- }
- return nbytes;
- }
-
- static long readlongfromsocket(gizmo_t *gp)
- {
- long val;
-
- if (gp->fd == 0) return 0;
- if (readbuf(gp->fd,(char *)&val,sizeof(val)) < 0) {
- (void)fprintf(stderr,"unknown data from socket\n");
- exit(0);
- }
- return val;
- }
-
- static void sendstringtogizmo(gizmo_t *gp, long type, char *s)
- {
- long buf[210], i = 2;
-
- buf[0] = type;
- buf[1] = -1;
-
- if (!s)
- goto lastwrite;
- do {
- buf[i++] = type;
- buf[i++] = *s++;
- } while (*s);
- lastwrite:
- if (write(gp->fd, buf, (unsigned int)(i*sizeof(long))) < 0) {
- if (gp && gp->pid) (void)kill(gp->pid,SIGTERM);
- }
- }
-
-
- /* The first item in the arg list must be a pointer to gizmo_t. The rest are
- * gizmo specific.
- */
-
- /*VARARGS*/
- #ifdef __cplusplus
- void doexec(gizmo_t *gizptr ...)
- #else
- void doexec(va_alist)
- va_dcl
- #endif
- {
- struct sockaddr_in saddr;
- int len, sock1, child, fd;
- char charportnum[100], *gargv[20];
- struct stat statbuf;
- va_list ap;
- gizmo_t *gp;
- long argno;
-
-
- #ifdef __cplusplus
- va_start(ap, gizptr);
- gp = gizptr;
- #else
- va_start(ap);
- gp = (gizmo_t *)va_arg(ap, gizmo_t *);
- #endif
- if (-1 == stat(gp->name,&statbuf)) {
- perror("stat error");
- exit(1);
- }
-
- sock1 = socket(AF_INET, SOCK_STREAM, 0);
- if(sock1 < 0) {
- perror("error opening socket");
- exit(1);
- }
-
- /* Create name for parent socket on local machine. */
-
- saddr.sin_family = AF_INET;
- saddr.sin_addr.s_addr = INADDR_ANY;
- saddr.sin_port = 0;
- if(bind(sock1, &saddr, sizeof(saddr))) {
- perror("binding parent socket");
- (void)close(sock1);
- exit(1);
- }
-
- /* Find out port number assigned to parent socket. */
-
- len = sizeof(saddr);
- if(getsockname(sock1, &saddr, &len)) {
- perror("getting parent socket name");
- (void)close(sock1);
- exit(1);
- }
-
- (void)listen(sock1, 1 /* max size of queue of waiting connectors */);
- child = (int)fork();
- if(child) {
- retry:
- fd = accept(sock1, 0, 0);
- if(fd == -1) {
- if (errno == EINTR)
- goto retry;
- (void)fprintf(stderr, "Failed to open gizmo.\nError %d", errno);
- (void)kill(child,SIGKILL);
- exit(1);
- }
- gp->fd = fd;
- gp->pid = child;
- if (gizmoptr == 0) {
- gizmoptr = gp;
- gp->next = 0;
- } else {
- gp->next = gizmoptr;
- gizmoptr = gp;
- }
- gp->state = GIZMOSTATE_OPEN;
- (void)close(sock1);
- } else {
- (void)close(sock1);
- (void)sprintf(charportnum, "%d", (int)ntohs(saddr.sin_port));
- gargv[0] = gp->name;
- gargv[1] = charportnum;
- for (argno = 2; gargv[argno] = (char *)va_arg(ap, char *); argno++) {
- /*printf("%s\n", gargv[argno]);*/
- ;
- }
- (void)execvp(gp->name, gargv);
- perror("exec failed");
- exit(1);
- }
- va_end();
- }
-
- /*
- * find the gizmo with the correct pid. We have gotten a signal that it
- * died.
- */
-
- void murdergizmos()
- {
- gizmo_t *gp;
-
- for (gp = gizmoptr; gp; gp = gp->next) {
- (void)kill(gp->pid,SIGTERM);
- (void)kill(gp->pid,SIGTERM);
- (void)kill(gp->pid,SIGTERM);
- (void)kill(gp->pid,SIGTERM);
- /* There! That ought to kill it fer sure! */
- }
- }
-
- /* Event reception *********************************************************/
-
- long getqevent(long *val, long *dev)
- {
- short sval;
-
- if (qtest() == 0) {*dev = 0; return 0; }
- *dev = qread(&sval);
- *val = sval;
- return 1;
- }
-
- int rawqread(long *val)
- {
- long dev, n;
- fd_set fdset;
- long buf[2];
- struct timeval timeout, *tp = &timeout;
- gizmo_t *gp;
-
- while(1) {
- tryagain:
- if (getqevent(val, &dev))
- return dev;
- FD_ZERO(&fdset);
- FD_SET(gd, &fdset);
- for (gp = gizmoptr; gp; gp = gp->next) {
- FD_SET(gp->fd, &fdset); /* do this for all gizmos */
- }
- tp = 0;
- while ((n = select(FD_SETSIZE, &fdset, (fd_set *)0, (fd_set *)0, tp)) < 0) {
- if (errno == EINTR) {
- goto tryagain;
- }
- perror("select");
- (void)fprintf(stderr, "select error");
- }
- for (gp = gizmoptr; gp; gp = gp->next) {
- if(FD_ISSET(gp->fd, &fdset)) { /* do this for all gizmos */
- if((n = readbuf(gp->fd, (char *)buf, sizeof(buf))) < 0) {
- perror("Error reading stream message");
- (void)kill(gp->pid,SIGKILL);
- }
- if (n == 0) {
- continue;
- }
- /* setmainwindow(); */
- *val = buf[1];
- return buf[0];
- }
- }
- if(FD_ISSET(gd, &fdset)) { /* grapics input queue non-empty */
- (void)getqevent(val, &dev);
- return dev;
- }
- }
- }
-
- extern long smearflag;
- extern short defaultwidth;
-
- long cookedqread(long *val)
- {
- long dev;
-
- dev = rawqread(val);
- if (dev == KEYBD && (getbutton(LEFTALTKEY) || getbutton(RIGHTALTKEY))) {
- switch (*val) {
- case 'n':
- return NEWCMD;
- case 'o':
- return OPENCMD;
- case 's':
- return SAVECMD;
- case 'S':
- return SAVEASCMD;
- case 'p':
- return PRINTCMD;
- case 'q':
- return QUITCMD;
- case 'Q':
- return QUITDAMMIT;
- case 'd': // delete
- return DELSELECTION;
- case 'e': // edit
- return EDITGEOM;
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- return C0 + *val - '0';
- case 'x':
- smearflag = 1 - smearflag; break;
- case 'l':
- defaultwidth = 3 - defaultwidth;
- break;
- }
- }
- return dev;
- }
-
- void centerovercursor(long *llx, long *urx, long *lly, long *ury, long width, long height)
- {
- *llx = getvaluator(MOUSEX) - width/2;
- *ury = getvaluator(MOUSEY) + height/2;
- if (*llx + width > getgdesc(GD_XPMAX))
- *llx = getgdesc(GD_XPMAX) - width -10;
- if (*ury - height < 0)
- *ury = height+10;
- *lly = *ury - height;
- *urx = *llx + width;
- }
-
- /* Exec-ing and killing gizmos ***********************************************/
-
- static void openbrowsegizmo(gizmo_t *gp, char *title, char *dir,
- char *buttonstring, char *accepttitle)
- {
- char cx[10], cy[10];
- long width = 340;
- long height = 450;
- long llx, lly, urx, ury;
-
- if (gp->state == GIZMOSTATE_OPEN) {
- /* need to init x, y, title, dir and buttonstring too */
- centerovercursor(&llx, &urx, &lly, &ury, width, height);
- senddevval(gp,GIZMOXORG ,llx);
- senddevval(gp,GIZMOYORG,lly);
- if (title) sendstringtogizmo(gp, TITLESTRDEV, title);
- if (dir) sendstringtogizmo(gp, DIRNAMEDEV ,dir);
- /* always send buttonstring to clear it if null */
- sendstringtogizmo(gp, BUTTONSTRDEV ,buttonstring );
- sendstringtogizmo(gp, ACCEPTSTRDEV ,accepttitle );
- senddev(gp, REINITEND);
- return;
- }
- centerovercursor(&llx, &urx, &lly, &ury, width, height);
- (void)sprintf(cx, "%d", (int)llx);
- (void)sprintf(cy, "%d", (int)lly);
- doexec(gp, "0", cx, cy, title, dir, buttonstring, accepttitle, 0);
- senddev(gp,GIZMOINITEND);
- }
-
- long getfilename(char *title,
- char *filename,
- char *buttonstring,
- char *dir,
- char *acceptbuttitle,
- long (*filetype)(char *))
- {
- long dev, val;
-
- *filename = 0;
- openbrowsegizmo(&browsegizmo, title, dir, buttonstring, acceptbuttitle);
- if (!browsegizmo.fd)
- return -1;
- while (1) {
- dev = cookedqread(&val);
- switch (dev) {
- case CREATEDEV:
- val = readlongfromsocket(&browsegizmo);
- /* this means they want to create a new thing */
- /* send FREEZE not ABORT, so process stays around */
- senddev(&browsegizmo, WINFREEZE);
- qreset(); qenter(REDRAW, 0);
- return 0;
- case DIRNAMEDEV:
- if (0 > readbuf(browsegizmo.fd, dir, (int)val)) {
- perror("Error reading stream message");
- (void)kill(browsegizmo.pid,SIGKILL);
- }
- break;
- case FILENAMEDEV:
- if (0 > readbuf(browsegizmo.fd, filename, (int)val)) {
- perror("Error reading stream message");
- (void)kill(browsegizmo.pid,SIGKILL);
- *filename = 0;
- return 0;
- }
- if (filetype && (!(*filetype)(filename))){
- *filename = 0;
- return getfilename(title, filename, buttonstring, dir, acceptbuttitle, filetype);
- }
- qreset(); qenter(REDRAW, 0);
- return 1;
- case ABORT: /* user chose CANCEL*/
- *filename = 0;
- qreset(); qenter(REDRAW, 0);
- return -1;
- default:
- senddev(&browsegizmo, POKEGIZMO);
- break;
- }
- }
- }
-